home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Extravaganza - Disc 1
/
ShareWare Extravaganza 1 of 4 (The Ultimate Shareware Company).iso
/
grprogs
/
picutil.exe
/
GMI2PIC.ASM
< prev
next >
Wrap
Assembly Source File
|
1986-05-27
|
22KB
|
568 lines
;╔═════════════════════════════════════════════════════════════════════════════╗
;║ ░░░░░░░░░░░ PROGRAM = PIC2IMG.ASM ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║
;╚═════════════════════════════════════════════════════════════════════════════╝
CSEG SEGMENT PUBLIC BYTE
ASSUME CS:CSEG,DS:CSEG
CR EQU 0DH
LF EQU 0AH
PIC DB 'PIC',0
IMG DB 'GMI',0
FILENAME DB 128 DUP(0)
HANDLE_IN DW 0
HANDLE_OUT DW 0
TYPE_FROM DW 0
LAST_CHAR DB 0
CHAR_COUNT DW 1
BYTE_CNT_H DW 0
BYTE_CNT_L DW 0
LINES_PER_READ DW 0
READS_PER_FILE DW 0
BYTES_PER_READ DW 0
DISK_BUFFER DD 0
;44 BYTES
IMG_NAME DB 'FILE GENERATED FROM PCPAINT '
IMG_HEIGHT DW 0
IMG_WIDTH DW 0
IMG_WIDTH_BYTE DW 0
IMG_PIX_SIZE DW 1
IMG_PIX_FMT DW 0
IMG_COLOR DW 0
IMG_COMPRESS DW 0
PIC_PAGE DW 1234H ;START OF PAGE
PIC_WIDTH DW 0 ;WIDTH OF IMAGE
PIC_HEIGHT DW 0 ;HEIGHT OF IMAGE
PIC_X_OFF DW 0 ;X OFFSET OF PIC
PIC_Y_OFF DW 0 ;Y OFFSET OF PIC
PIC_PIX_SIZE DB 1 ;SIZE OF PEL
PIC_2 DB 0FFH ;PCPAINT 2.0
PIC_MODE DB 'G' ;TYPE OF DISPLAY
PIC_DESC DW 0 ;DESCRIPTOR
PIC_COUNT DW 0 ;COUNT
PIC_BLOCK DW 1 ;NUMBER OF PACKED BLOCKS
PIC_PAC_SZ DW 0 ;NUMBER OF PACKED BYTES IN BLOCK
PIC_NORM DW 0 ;NUMBER OF BYTES UNPACKED
PIC_ID DB 0 ;IDENTIFIER
TELL_HOW DB '┌──────────────────────────────────────────────┐',cr,lf
DB '│ GMI2PIC filename.typ │',cr,lf
DB '├──────────────────────────────────────────────┤',cr,lf
DB '│ filename = GMI file created with MIRROR.EXE │',cr,lf
DB '│ typ = must end in GMI │',cr,lf
DB '├──────────────────────────────────────────────┤',cr,lf
DB '│ Converts GMI (reverse image file to PIC file │',cr,lf
DB '│ PIC file = PC-Paint Plus format (Mouse Sys) │',cr,lf
DB '└──────────────────────────────────────────────┘',cr,lf
DB 7,'$'
OPEN_ERROR DB 'file not found...must end in GMI',cr,lf,'$'
CREATE_ERROR DB 'create error on output file',cr,lf,'$'
;╔═════════════════════════════════════════════════════════════════════════════╗
;║ ░░░░░░░░░░░ MAIN.ASM ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║
;╚═════════════════════════════════════════════════════════════════════════════╝
MAIN PROC FAR
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ RETURN SETUP │
;└─────────────────────────────────────────────────────────────────────────────┘
CLI
MOV AX,CS ;TEMP STACK
MOV SS,AX ;
MOV ES,AX ;
MOV SP,OFFSET STACK ;
STI
PUSH DS ;
XOR AX,AX ;
PUSH AX ;
CLD
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ GET FILENAME FROM COMMAND LINE │
;└─────────────────────────────────────────────────────────────────────────────┘
MOV SI,82H ;START OF FILENAME
XOR CH,CH ;
MOV CL,DS:[SI-2] ;SIZE OF FILENAME
CMP CX,0 ;NO COMMANDS
JE GFN800 ;ERROR
MOV DI,OFFSET FILENAME ;STORE FILENAME HERE
GFN100:
LODSB ;GET CHARACTER
CMP AL,20H ;END OF FILENAME?
JE GFN900 ;YES....BRANCH
CMP AL,CR ;END OF COMMAND LINE?
JE GFN900 ;YES....ERROR
STOSB ;SAVE CHARACTER
CMP AL,'.' ;START OF TYPE
JNE GFN200 ;
MOV CS:TYPE_FROM,DI ;START OF TYPE
GFN200:
LOOP GFN100 ;GET ANOTHER CHARACTER
JMP SHORT GFN800 ;ERROR IF DONE ALREADY
GFN800:
MOV DX,OFFSET TELL_HOW ;
JMP ERROR ;
GFN900:
MOV AL,0 ;PUT NULL AT END OF STRING
STOSB ;
CMP WORD PTR CS:TYPE_FROM,0 ;
JNE SET_BREAK
DEC DI
MOV CS:TYPE_FROM,DI
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ TURN BREAK KEY ON │
;└─────────────────────────────────────────────────────────────────────────────┘
SET_BREAK:
MOV AX,CS ;SET DATA SEGMENT
MOV DS,AX ;
CALL BREAK_ON ;SET UP CONTROL BREAK
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ FIND DISK MEMORY │
;└─────────────────────────────────────────────────────────────────────────────┘
MOV AX,OFFSET PROG_END ;
MOV BX,CS ;
SHR AX,1 ;
SHR AX,1 ;
SHR AX,1 ;
SHR AX,1 ;
ADD BX,AX ;
ADD BX,8 ;
MOV WORD PTR DISK_BUFFER+2,BX ;
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ CHECK FILENAME │
;└─────────────────────────────────────────────────────────────────────────────┘
MOV SI,OFFSET IMG ;CHANGE TYPE ON FILENAME
MOV DI,TYPE_FROM ;
MOV CX,3 ;
AND BYTE PTR [DI],0DFH ;MAKE CAPITOL LETTER
AND BYTE PTR [DI+1],0DFH ;MAKE CAPITOL LETTER
AND BYTE PTR [DI+2],0DFH ;MAKE CAPITOL LETTER
REP CMPSB ;
JNE OIF050
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ OPEN INPUT FILE │
;└─────────────────────────────────────────────────────────────────────────────┘
MOV AH,3DH ;OPEN FILE FOR READ
MOV AL,0H ;
MOV DX,OFFSET FILENAME ;
INT 21H ;
JNC OIF100
OIF050:
MOV DX,OFFSET OPEN_ERROR ;
JMP ERROR
OIF100:
MOV HANDLE_IN,AX
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ CHANGE FILENAME │
;└─────────────────────────────────────────────────────────────────────────────┘
MOV SI,OFFSET PIC ;CHANGE TYPE ON FILENAME
MOV DI,TYPE_FROM ;
MOV CX,3 ;
REP MOVSB ;
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ CREATE OUTPUT TEMP FILE │
;└─────────────────────────────────────────────────────────────────────────────┘
MOV AH,3CH ;
MOV CX,20H ;
MOV DX,OFFSET FILENAME ;
INT 21H ;
JNC COF100
MOV DX,OFFSET CREATE_ERROR ;
JMP ERROR
COF100:
MOV HANDLE_OUT,AX
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ READ IMG HEADER │
;└─────────────────────────────────────────────────────────────────────────────┘
MOV AH,3FH
MOV BX,HANDLE_IN
MOV CX,44
MOV DX,OFFSET IMG_NAME
INT 21H
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ TRANSLATE TO PIC HEADER │
;└─────────────────────────────────────────────────────────────────────────────┘
MOV AX,IMG_HEIGHT ;GET IMG HEIGHT
MOV PIC_HEIGHT,AX ;MOV TO PIC HEIGHT
MOV AX,IMG_WIDTH_BYTE ;GET IMG WIDTH
SHL AX,1
SHL AX,1
SHL AX,1
MOV PIC_WIDTH,AX ;MOV TO PIC WIDTH
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ CALCULATE NUMBER OF BLOCKS │
;└─────────────────────────────────────────────────────────────────────────────┘
MOV AX,IMG_HEIGHT ;LINES * BYTES PER LINE =
MOV CX,IMG_WIDTH_BYTE ; FILE SIZE
MUL CX ;DX:AX = FILE SIZE
MOV BYTE_CNT_L,AX ;SAVE SIZE
MOV BYTE_CNT_H,DX ;
MOV CX,2000H ;MAX PIC PACKET SIZE
DIV CX ;AX = NUMBER OF PACKETS -1
INC AX
MOV PIC_BLOCK,AX
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ WRITE PIC HEADER │
;└─────────────────────────────────────────────────────────────────────────────┘
MOV AH,40H
MOV BX,HANDLE_OUT
MOV CX,19
MOV DX,OFFSET PIC_PAGE
INT 21H
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ MOVE PICTURE DATA BETWEEN FILES │
;└─────────────────────────────────────────────────────────────────────────────┘
READ_BLOCK:
CALL PROCESS_PAC
DEC PIC_BLOCK
JZ CLOSE_FILE
JMP READ_BLOCK
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ CLOSE FILES │
;└─────────────────────────────────────────────────────────────────────────────┘
CLOSE_FILE:
MOV BX,HANDLE_IN ;CLOSE FILE
MOV AH,3EH ;
INT 21H ;
MOV BX,HANDLE_OUT ;CLOSE FILE
MOV AH,3EH ;
INT 21H ;
JMP EXIT
ERROR:
MOV AX,CS
MOV DS,AX
MOV AH,9
INT 21H
EXIT:
CALL BREAK_OFF ;BREAK KEY RESET
RET ;
MAIN ENDP
;╔═════════════════════════════════════════════════════════════════════════════╗
;║ ░░░░░░░░░░░ PROCESS PACKET ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║
;╚═════════════════════════════════════════════════════════════════════════════╝
PROCESS_PAC PROC NEAR
CALL READ_IMAGE ;AX = NUMBER OF BYTES READ
CMP AX,0
JE PP200
SUB BYTE_CNT_L,AX
JNC PP100
CMP BYTE_CNT_H,0
JE PP050
DEC BYTE_CNT_H
JMP SHORT PP100
PP050:
ADD BYTE_CNT_L,AX
MOV AX,BYTE_CNT_L
PP100:
CALL PAC_IMAGE
CALL WRITE_PAC_HDR
CALL WRITE_PAC
PP200:
RET
PROCESS_PAC ENDP
;╔═════════════════════════════════════════════════════════════════════════════╗
;║ ░░░░░░░░░░░ WRITE_PAC_HEADER ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║
;╚═════════════════════════════════════════════════════════════════════════════╝
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ WRITE 5 BYTE PACKET HEADER │
;└─────────────────────────────────────────────────────────────────────────────┘
WRITE_PAC_HDR PROC NEAR
PUSH AX ;SAVE REGISTERS
PUSH BX ;
PUSH CX ;
PUSH DX ;
;
MOV AH,40H ;
MOV BX,HANDLE_OUT ;
MOV CX,5 ;
MOV DX,OFFSET PIC_PAC_SZ ;
INT 21H ;
;
POP DX ;RESTORE REGISTERS
POP CX ;
POP BX ;
POP AX ;
RET
WRITE_PAC_HDR ENDP
;╔═════════════════════════════════════════════════════════════════════════════╗
;║ ░░░░░░░░░░░ WRITE PACKET ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║
;╚═════════════════════════════════════════════════════════════════════════════╝
WRITE_PAC PROC NEAR
PUSH AX ;SAVE REGISTERS
PUSH BX ;
PUSH CX ;
PUSH DX ;
PUSH DS
;
MOV AH,40H ;
MOV BX,HANDLE_OUT ;
MOV CX,PIC_PAC_SZ ;
SUB CX,5 ;NO NEED TO WRITE HEADER
LDS DX,DISK_BUFFER ;
ADD DX,8000H ;
INT 21H ;
;
POP DS
POP DX ;RESTORE REGISTERS
POP CX ;
POP BX ;
POP AX ;
RET
WRITE_PAC ENDP
;╔═════════════════════════════════════════════════════════════════════════════╗
;║ ░░░░░░░░░░░ PAC IMAGE ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║
;╚═════════════════════════════════════════════════════════════════════════════╝
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ COMPRESS PACKET │
;└─────────────────────────────────────────────────────────────────────────────┘
PAC_IMAGE PROC NEAR
PUSH AX ;SAVE REGISTERS
PUSH BX ;
PUSH CX ;
PUSH DX ;
PUSH DI ;
PUSH SI ;
PUSH DS ;
PUSH ES ;
cld
MOV PIC_NORM,AX ;SIZE OF PACKET
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ CLEAR FLAGS BUFFER │
;└─────────────────────────────────────────────────────────────────────────────┘
PUSH AX
MOV AX,CS
MOV ES,AX
XOR AX,AX
MOV DI,OFFSET FLAGS
MOV CX,256
REP STOSB
POP AX
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ FIND CHARACTER IN PACKET NOT USED │
;└─────────────────────────────────────────────────────────────────────────────┘
PUSH AX
MOV CX,AX ;USE AS COUNTER
PUSH DS ;SET ES TO DS
POP ES ;LOOK THROUGH BUFFER AND
LDS SI,DISK_BUFFER ;FLAG ANY CHARACTER USED
MOV DI,OFFSET FLAGS ;
FC400:
LODSB ;GET CHARACTER
MOV BL,AL ;SETUP OFFSET WITH CHARACTER
XOR BH,BH ;
INC BYTE PTR ES:[DI+BX] ;SET FLAG FOR CHARACTER
LOOP FC400 ;DO UNTIL DONE
PUSH ES ;RESTORE DS
POP DS ;
FC500:
MOV SI,OFFSET FLAGS ;
XOR AL,AL
FC525:
MOV CX,256 ;
XOR BX,BX
FC550:
CMP BYTE PTR DS:[SI+BX],AL
JE FC600 ;NO...USE IT FOR ID TAG
INC BX
LOOP FC550
INC AL ;LOOK FOR NEXT LEAST USED CHAR.
JMP SHORT FC525
FC600:
MOV PIC_ID,BL
POP CX ;RESTORE BUFFER SIZE
;┌─────────────────────────────────────────────────────────────────────────────┐
;│ START COMPRESSION │
;└─────────────────────────────────────────────────────────────────────────────┘
LES DI,DISK_BUFFER ;DESTINATION
ADD DI,8000H ;
LDS SI,DISK_BUFFER ;SOURCE
LODSB
MOV CS:LAST_CHAR,AL ;
SC100:
LODSB ;
CMP AL,CS:LAST_CHAR ;
JNE SC300 ;
INC CS:CHAR_COUNT ;
LOOP SC100 ;
SC300:
PUSH AX ;SAVE NEW CHARACTER
CMP CS:CHAR_COUNT,4 ;IS IT MORE THAN 3 CHARACTERS
JB SC500 ;NO PRINT 3 CHARACTERS
SC325:
MOV AL,CS:PIC_ID ;GET TAG CHARACTER
STOSB
MOV BX,CS:CHAR_COUNT ;
CMP BH,0 ;16 BIT?
JNE SC400
MOV AL,BL
STOSB
SC350:
MOV AL,CS:LAST_CHAR
STOSB
JMP SHORT SC700
SC400:
MOV AL,0
STOSB
MOV AX,BX
STOSW
JMP SHORT SC350
SC500: ;NOT MORE THAN 3 IN A ROW
MOV AL,CS:LAST_CHAR ;PRINT CHARACTERS
CMP AL,CS:PIC_ID ;IS IT ID BYTE
JE SC325 ;SEND AS STRING
SC600:
STOSB ;
DEC CS:CHAR_COUNT ;
JNZ SC600 ;
SC700: ;
POP AX ;
MOV CS:LAST_CHAR,AL ;
MOV CS:CHAR_COUNT,1 ;
CMP CX,0
LOOPNZ SC100
SUB DI,8000H-5
MOV CS:PIC_PAC_SZ,DI
POP ES ;RESTORE REGISTERS
POP DS ;
POP SI ;
POP DI ;
POP DX ;
POP CX ;
POP BX ;
POP AX ;
RET
PAC_IMAGE ENDP
;╔═════════════════════════════════════════════════════════════════════════════╗
;║ ░░░░░░░░░░░ READ IMAGE ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║
;╚═════════════════════════════════════════════════════════════════════════════╝
READ_IMAGE PROC NEAR
PUSH BX ;
PUSH CX ;
PUSH DX ;
PUSH DS
MOV AH,3FH ;
MOV BX,HANDLE_IN ;
MOV CX,2000H ;
LDS DX,DISK_BUFFER ;
INT 21H ;
POP DS
POP DX ;RESTORE REGISTERS
POP CX ;
POP BX ;
RET
READ_IMAGE ENDP
;┌─────────────────────────────────────────────────────────────────────────────┐
;└─────────────────────────────────────────────────────────────────────────────┘
EOI EQU 20H ;END OF INTERRUPT
BRKINT EQU 1BH ;BREAK INTERRUPT
SAV_BRK DW ?
;╔═════════════════════════════════════════════════════════════════════════════╗
;║ ░░░░░░░░░░ BREAK_ON ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║
;╚═════════════════════════════════════════════════════════════════════════════╝
PUBLIC BREAK_ON
BREAK_ON PROC NEAR
PUSH AX
PUSH BX ;SAVE REGISTERS
PUSH CX ;
PUSH DX ;
PUSH SI ;
PUSH ES ;
XOR BX,BX ;SEGMENT 0
MOV ES,BX ;
MOV SI,BRKINT*4 ;OFFSET OF INTERUPT VECTOR
MOV CX,ES:WORD PTR[SI] ;OFFSET OF CURRENT VECT
MOV DX,ES:WORD PTR[SI+2] ;SEGMENT OF CURRENT VECT
MOV CS:SAV_BRK,CX ;SAVE OFFSET
MOV CS:SAV_BRK+2,DX ;SAVE SEGMENT
MOV AX,OFFSET BREAK ;
CLI ;NO INTERRUPTS
MOV ES:WORD PTR[SI],AX ;SET OFFSET
MOV AX,CS ;SET THIS CODE SEGMENT
MOV ES:WORD PTR[SI+2],AX ;MOVE SEG ADDR TO INT.VECT
STI ;INTERRUPTS BACK ON
POP ES ;RESTORE REGISTERS
POP SI ;
POP DX ;
POP CX ;
POP BX ;
POP AX ;
RET ;
BREAK_ON ENDP
;╔═════════════════════════════════════════════════════════════════════════════╗
;║ ░░░░░░░░░░ BREAK_OFF ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║
;╚═════════════════════════════════════════════════════════════════════════════╝
PUBLIC BREAK_OFF
BREAK_OFF PROC NEAR
PUSH AX ;
PUSH CX ;
PUSH DX ;
PUSH DI ;
PUSH ES ;
XOR AX,AX ;
MOV ES,AX ;SEGMENT 0
MOV CX,CS:SAV_BRK ;RESET VECTOR BACK TO OLD RTN
MOV DX,CS:SAV_BRK+2 ;
MOV DI,BRKINT*4 ;
CLI ;NO INTERRUPTS
MOV ES:WORD PTR[DI],CX ;
MOV ES:WORD PTR[DI+2],DX ;
STI ;INTERRUPTS BACK ON
POP ES ;
POP DI ;
POP DX ;
POP CX ;
POP AX ;
RET ;
BREAK_OFF ENDP
;╔═════════════════════════════════════════════════════════════════════════════╗
;║ ░░░░░░░░░░ BREAK ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║ J
;╚═════════════════════════════════════════════════════════════════════════════╝
PUBLIC BREAK
BREAK PROC FAR
MOV AX,CS
MOV DS,AX
MOV AL,EOI ;
OUT 020H,AL ;
CALL BREAK_OFF
MOV SP,OFFSET STACK-4 ;
RET
BREAK ENDP
;┌─────────────────────────────────────────────────────────────────────────────┐
;└─────────────────────────────────────────────────────────────────────────────┘
FLAGS DB 256 DUP(0)
DB 64 DUP('STACK')
STACK EQU $
PROG_END EQU $
CSEG ENDS
END MAIN